package com.och.mrcp.core.mrcp.model;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Map;

/**
 * MRCPv2事件消息
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class MrcpEvent extends MrcpMessage {
    
    // 事件类型
    public enum EventType {
        // 语音合成事件
        SPEAK_START("SPEAK-START"),
        SPEAK_COMPLETE("SPEAK-COMPLETE"),
        SPEAK_FAILED("SPEAK-FAILED"),
        
        // 语音识别事件
        RECOGNITION_COMPLETE("RECOGNITION-COMPLETE"),
        RECOGNITION_FAILED("RECOGNITION-FAILED"),
        INTERPRETATION_COMPLETE("INTERPRETATION-COMPLETE"),
        INTERPRETATION_FAILED("INTERPRETATION-FAILED"),
        RECOGNITION_START_TIMERS("RECOGNITION-START-TIMERS"),
        
        // 通用事件
        START_OF_INPUT("START-OF-INPUT"),
        END_OF_INPUT("END-OF-INPUT");
        
        private final String value;
        
        EventType(String value) {
            this.value = value;
        }
        
        public String getValue() {
            return value;
        }
        
        public static EventType fromString(String value) {
            for (EventType type : values()) {
                if (type.value.equalsIgnoreCase(value)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown event type: " + value);
        }
    }
    
    private EventType eventType;
    private String requestId;  // 添加requestId字段
    
    public MrcpEvent() {
        super();
        this.messageType = MessageType.EVENT;
    }
    
    public MrcpEvent(ResourceType resourceType, EventType eventType) {
        this();
        this.resourceType = resourceType;
        this.eventType = eventType;
    }
    
    @Override
    public boolean isValid() {
        return resourceType != null && 
               eventType != null && 
               messageId != null && 
               !messageId.isEmpty();
    }
    
    @Override
    public String encode() {
        StringBuilder sb = new StringBuilder();
        
        // 第一行：MRCP版本 + 消息长度 + 事件名称 + 请求ID + 请求状态
        // 格式：MRCP/2.0 <message-length> <event-name> <request-id> <request-state>
        int messageLength = calculateMessageLength();
        sb.append("MRCP/").append(MRCP_VERSION).append(" ")
          .append(messageLength).append(" ")
          .append(eventType != null ? eventType.getValue() : "UNKNOWN").append(" ")
          .append(requestId != null ? requestId : "0").append(" ")
          .append(getRequestState() != null ? getRequestState() : "IN-PROGRESS").append("\r\n");
        
        // 头部字段
        headers.forEach((name, value) -> 
            sb.append(name).append(": ").append(value).append("\r\n"));
        
        // 空行分隔头部和消息体
        sb.append("\r\n");
        
        // 消息体
        if (body != null && !body.isEmpty()) {
            sb.append(body);
        }
        
        return sb.toString();
    }
    
    /**
     * 计算消息长度
     * RFC 6787: 消息长度包括头部字段、空行分隔符和消息体，但不包括起始行
     * 对于标准错误事件（如RECOGNITION-COMPLETE），使用0
     */
    private int calculateMessageLength() {
        // 检查是否为标准错误事件（只有基本头部字段且无消息体）
        boolean isStandardErrorEvent = (body == null || body.isEmpty()) && 
                                     headers.size() <= 2 && 
                                     (headers.containsKey("Channel-Identifier") || headers.containsKey("Completion-Cause")) &&
                                     eventType == EventType.RECOGNITION_COMPLETE;
        
        if (isStandardErrorEvent) {
            return 0; // 标准错误事件使用0长度
        }
        
        try {
            // 计算头部长度（使用UTF-8编码）
            int headerLength = 0;
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String headerLine = entry.getKey() + ": " + entry.getValue() + "\r\n";
                headerLength += headerLine.getBytes("UTF-8").length;
            }
            
            // 计算消息体长度（使用UTF-8编码）
            int bodyLength = 0;
            if (body != null && !body.isEmpty()) {
                bodyLength = body.getBytes("UTF-8").length;
            }
            
            // 空行分隔符长度
            int separatorLength = "\r\n".getBytes("UTF-8").length;
            
            // 总长度 = 头部长度 + 空行分隔符 + 消息体长度
            return headerLength + separatorLength + bodyLength;
        } catch (Exception e) {
            // 如果UTF-8编码失败，回退到默认计算方式
            int headerLength = 0;
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                headerLength += entry.getKey().length() + ": ".length() + entry.getValue().length() + "\r\n".length();
            }
            int bodyLength = body != null ? body.length() : 0;
            int separatorLength = "\r\n".length();
            return headerLength + separatorLength + bodyLength;
        }
    }
    
    @Override
    public String getMessageTypeDescription() {
        return "MRCPv2 Event: " + (eventType != null ? eventType.getValue() : "UNKNOWN");
    }
    
    /**
     * 设置请求ID
     */
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
    
    /**
     * 获取请求ID
     */
    public String getRequestId() {
        return requestId;
    }
}
